#include "PrecompiledHeader.h"
#include "IParticlesEmitterObject.h"

/*--------------------------------------------------------------------------*/

IParticlesEmitterObject::IParticlesEmitterObject(const NodeCreation& nc) :
	INode(ENodeFlag::NoActive | ENodeFlag::NoChildren, nc.m_parent, nc.m_scene)
{
	RenderTaskDesc desc;
	desc.m_material = g_Material->GetMaterial("mat_particles");
	desc.m_argument = 0;
	desc.m_flags = ERenderTaskFlag::Particles | ERenderTaskFlag::Transparent;
	desc.m_priority = 0;

	this->AddRenderTask(desc);

	/*--------------------------------------------------------------------------*/

// 	this->SetRadius(20.0f);
// 	this->SetScale(1.0f);
// 	this->SetRotation(glm::vec3());

	for (int i = 0; i < 25; ++i)
	{
		Particle p(10.0f + rand() % 1000 / 100.0f);
		p.SetDirection(this->m_direction + glm::vec3((rand() % 1000 - 500) / 1000.0f, (rand() % 1000 - 500) / 1000.0f, (rand() % 1000 - 500) / 1000.0f));

		this->m_particles.push_back(p);
	}
}

/*--------------------------------------------------------------------------*/

IParticlesEmitterObject::~IParticlesEmitterObject()
{

}

/*--------------------------------------------------------------------------*/

uint IParticlesEmitterObject::TreeCalc(uint arg)
{
	__super::TreeCalc();

	if (this->GetFlags() & ENodeFlag::NoRender)
	{
		return 0;
	}

	/*--------------------------------------------------------------------------*/

	this->SetTranslation(this->GetRelativePosition());
	this->CalcModelMatrices();

	this->BindRenderTask(this->GetSceneInstance()->GetRenderPhase(), 0);
#ifdef VL_RENDER_STATISTICS
	g_Hud->GetStatisticsManager()->IncrementStatistic("IParticlesEmitterObject/Success");
#endif

	return 0;
}

/*--------------------------------------------------------------------------*/

void IParticlesEmitterObject::OnRender(const uint i, ERenderQuality::Type quality)
{
	switch (i)
	{
	case 0:
	{
// 		ICamera* cam = g_Camera->GetActiveCamera();
//
// 		glm::vec3 cameraStrafeDirection = cam->GetStrafeDirection() / 2.0f;
// 		glm::vec3 cameraJumpDirection = cam->GetJumpDirection() / 2.0f;

// 		OpenGL::RawBegin(GL_QUADS);
//
// 		for (std::vector<Particle>::iterator it = this->m_particles.begin(); it != this->m_particles.end(); ++it)
// 		{
// 			float factor = 100.0f / (it->GetLifetime());
//
// 			glm::vec3 p = (*it).GetPosition();
// 			OpenGL::RawDrawRectangle((p - cameraStrafeDirection - cameraJumpDirection) * factor,
// 			                         (p + cameraStrafeDirection - cameraJumpDirection) * factor,
// 			                         (p + cameraStrafeDirection + cameraJumpDirection) * factor,
// 			                         (p - cameraStrafeDirection + cameraJumpDirection) * factor);
// 		}
//
// 		OpenGL::RawEnd();

		break;
	}

	}

}

/*--------------------------------------------------------------------------*/

void IParticlesEmitterObject::CalculateParticlesMovement(float step)
{
	for (std::vector<Particle>::iterator it = this->m_particles.begin(); it != this->m_particles.end(); ++it)
	{
		if (!(*it).Calculate(step))
		{
			(*it).SetPosition(glm::vec3());
			(*it).SetLifetime(10.0f + rand() % 1000 / 100.0f);
		}
	}
}

/*--------------------------------------------------------------------------*/

void IParticlesEmitterObject::SetDirection(const glm::vec3& direction)
{
	this->m_direction = direction;
}

/*--------------------------------------------------------------------------*/

const glm::vec3& IParticlesEmitterObject::GetDirection() const
{
	return this->m_direction;
}

/*--------------------------------------------------------------------------*/

void IParticlesEmitterObject::SetStrength(const float& strength)
{
	this->m_strength = strength;
}

/*--------------------------------------------------------------------------*/

const float& IParticlesEmitterObject::GetStrength() const
{
	return this->m_strength;
}

/*--------------------------------------------------------------------------*/

void IParticlesEmitterObject::SetSpread(const float& spread)
{
	this->m_spread = spread;
}

/*--------------------------------------------------------------------------*/

const float& IParticlesEmitterObject::GetSpread() const
{
	return this->m_spread;
}

/*--------------------------------------------------------------------------*/

void IParticlesEmitterObject::SetFrequency(const float& freq)
{
	this->m_frequency = freq;
}

/*--------------------------------------------------------------------------*/

const float& IParticlesEmitterObject::GetFrequency() const
{
	return this->m_frequency;
}

/*--------------------------------------------------------------------------*/